{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "logistic_regression.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "collapsed_sections": [
        "dPpJUV862FYI",
        "i2e3TlyL57Qs",
        "wCugvl0JdWYL",
        "copyright-notice"
      ]
    },
    "kernelspec": {
      "name": "python2",
      "display_name": "Python 2"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "copyright-notice",
        "colab_type": "text"
      },
      "source": [
        "#### Copyright 2017 Google LLC."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "copyright-notice2",
        "colab_type": "code",
        "cellView": "both",
        "colab": {}
      },
      "source": [
        "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "g4T-_IsVbweU",
        "colab_type": "text"
      },
      "source": [
        " # 逻辑回归"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LEAHZv4rIYHX",
        "colab_type": "text"
      },
      "source": [
        " **学习目标：**\n",
        "  * 将（在之前的练习中构建的）房屋价值中位数预测模型重新构建为二元分类模型\n",
        "  * 比较逻辑回归与线性回归解决二元分类问题的有效性"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CnkCZqdIIYHY",
        "colab_type": "text"
      },
      "source": [
        " 与在之前的练习中一样，我们将使用加利福尼亚州住房数据集，但这次我们会预测某个城市街区的住房成本是否高昂，从而将其转换成一个二元分类问题。此外，我们还会暂时恢复使用默认特征。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9pltCyy2K3dd",
        "colab_type": "text"
      },
      "source": [
        " ## 将问题构建为二元分类问题\n",
        "\n",
        "数据集的目标是 `median_house_value`，它是一个数值（连续值）特征。我们可以通过向此连续值使用阈值来创建一个布尔值标签。\n",
        "\n",
        "我们希望通过某个城市街区的特征预测该街区的住房成本是否高昂。为了给训练数据和评估数据准备目标，我们针对房屋价值中位数定义了分类阈值 - 第 75 百分位数（约为 265000）。所有高于此阈值的房屋价值标记为 `1`，其他值标记为 `0`。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "67IJwZX1Vvjt",
        "colab_type": "text"
      },
      "source": [
        " ## 设置\n",
        "\n",
        "运行以下单元格，以加载数据并准备输入特征和目标。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "fOlbcJ4EIYHd",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "from __future__ import print_function\n",
        "\n",
        "import math\n",
        "\n",
        "from IPython import display\n",
        "from matplotlib import cm\n",
        "from matplotlib import gridspec\n",
        "from matplotlib import pyplot as plt\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "from sklearn import metrics\n",
        "import tensorflow as tf\n",
        "from tensorflow.python.data import Dataset\n",
        "\n",
        "tf.logging.set_verbosity(tf.logging.ERROR)\n",
        "pd.options.display.max_rows = 10\n",
        "pd.options.display.float_format = '{:.1f}'.format\n",
        "\n",
        "california_housing_dataframe = pd.read_csv(\"https://download.mlcc.google.cn/mledu-datasets/california_housing_train.csv\", sep=\",\")\n",
        "\n",
        "california_housing_dataframe = california_housing_dataframe.reindex(\n",
        "    np.random.permutation(california_housing_dataframe.index))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lTB73MNeIYHf",
        "colab_type": "text"
      },
      "source": [
        " 注意以下代码与之前练习中的代码之间稍有不同。我们并没有将 `median_house_value` 用作目标，而是创建了一个新的二元目标 `median_house_value_is_high`。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kPSqspaqIYHg",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def preprocess_features(california_housing_dataframe):\n",
        "  \"\"\"Prepares input features from California housing data set.\n",
        "\n",
        "  Args:\n",
        "    california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
        "      from the California housing data set.\n",
        "  Returns:\n",
        "    A DataFrame that contains the features to be used for the model, including\n",
        "    synthetic features.\n",
        "  \"\"\"\n",
        "  selected_features = california_housing_dataframe[\n",
        "    [\"latitude\",\n",
        "     \"longitude\",\n",
        "     \"housing_median_age\",\n",
        "     \"total_rooms\",\n",
        "     \"total_bedrooms\",\n",
        "     \"population\",\n",
        "     \"households\",\n",
        "     \"median_income\"]]\n",
        "  processed_features = selected_features.copy()\n",
        "  # Create a synthetic feature.\n",
        "  processed_features[\"rooms_per_person\"] = (\n",
        "    california_housing_dataframe[\"total_rooms\"] /\n",
        "    california_housing_dataframe[\"population\"])\n",
        "  return processed_features\n",
        "\n",
        "def preprocess_targets(california_housing_dataframe):\n",
        "  \"\"\"Prepares target features (i.e., labels) from California housing data set.\n",
        "\n",
        "  Args:\n",
        "    california_housing_dataframe: A Pandas DataFrame expected to contain data\n",
        "      from the California housing data set.\n",
        "  Returns:\n",
        "    A DataFrame that contains the target feature.\n",
        "  \"\"\"\n",
        "  output_targets = pd.DataFrame()\n",
        "  # Create a boolean categorical feature representing whether the\n",
        "  # median_house_value is above a set threshold.\n",
        "  output_targets[\"median_house_value_is_high\"] = (\n",
        "    california_housing_dataframe[\"median_house_value\"] > 265000).astype(float)\n",
        "  return output_targets"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "FwOYWmXqWA6D",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1209
        },
        "outputId": "392bf841-487b-4f5f-9796-253f48d4f8f0"
      },
      "source": [
        "# Choose the first 12000 (out of 17000) examples for training.\n",
        "training_examples = preprocess_features(california_housing_dataframe.head(12000))\n",
        "training_targets = preprocess_targets(california_housing_dataframe.head(12000))\n",
        "\n",
        "# Choose the last 5000 (out of 17000) examples for validation.\n",
        "validation_examples = preprocess_features(california_housing_dataframe.tail(5000))\n",
        "validation_targets = preprocess_targets(california_housing_dataframe.tail(5000))\n",
        "\n",
        "# Double-check that we've done the right thing.\n",
        "print(\"Training examples summary:\")\n",
        "display.display(training_examples.describe())\n",
        "print(\"Validation examples summary:\")\n",
        "display.display(validation_examples.describe())\n",
        "\n",
        "print(\"Training targets summary:\")\n",
        "display.display(training_targets.describe())\n",
        "print(\"Validation targets summary:\")\n",
        "display.display(validation_targets.describe())"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Training examples summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "       latitude  longitude  ...  median_income  rooms_per_person\n",
              "count   12000.0    12000.0  ...        12000.0           12000.0\n",
              "mean       35.6     -119.6  ...            3.9               2.0\n",
              "std         2.1        2.0  ...            1.9               1.1\n",
              "min        32.5     -124.3  ...            0.5               0.0\n",
              "25%        33.9     -121.8  ...            2.6               1.5\n",
              "50%        34.2     -118.5  ...            3.6               1.9\n",
              "75%        37.7     -118.0  ...            4.8               2.3\n",
              "max        42.0     -114.3  ...           15.0              52.0\n",
              "\n",
              "[8 rows x 9 columns]"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>latitude</th>\n",
              "      <th>longitude</th>\n",
              "      <th>housing_median_age</th>\n",
              "      <th>total_rooms</th>\n",
              "      <th>total_bedrooms</th>\n",
              "      <th>population</th>\n",
              "      <th>households</th>\n",
              "      <th>median_income</th>\n",
              "      <th>rooms_per_person</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "      <td>12000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>35.6</td>\n",
              "      <td>-119.6</td>\n",
              "      <td>28.5</td>\n",
              "      <td>2635.9</td>\n",
              "      <td>536.8</td>\n",
              "      <td>1421.0</td>\n",
              "      <td>498.3</td>\n",
              "      <td>3.9</td>\n",
              "      <td>2.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>2.1</td>\n",
              "      <td>2.0</td>\n",
              "      <td>12.6</td>\n",
              "      <td>2144.2</td>\n",
              "      <td>415.7</td>\n",
              "      <td>1082.2</td>\n",
              "      <td>377.6</td>\n",
              "      <td>1.9</td>\n",
              "      <td>1.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>32.5</td>\n",
              "      <td>-124.3</td>\n",
              "      <td>1.0</td>\n",
              "      <td>11.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>0.5</td>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>33.9</td>\n",
              "      <td>-121.8</td>\n",
              "      <td>18.0</td>\n",
              "      <td>1466.8</td>\n",
              "      <td>296.0</td>\n",
              "      <td>792.0</td>\n",
              "      <td>281.8</td>\n",
              "      <td>2.6</td>\n",
              "      <td>1.5</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>34.2</td>\n",
              "      <td>-118.5</td>\n",
              "      <td>29.0</td>\n",
              "      <td>2122.5</td>\n",
              "      <td>434.0</td>\n",
              "      <td>1170.0</td>\n",
              "      <td>408.0</td>\n",
              "      <td>3.6</td>\n",
              "      <td>1.9</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>37.7</td>\n",
              "      <td>-118.0</td>\n",
              "      <td>37.0</td>\n",
              "      <td>3146.0</td>\n",
              "      <td>646.0</td>\n",
              "      <td>1720.0</td>\n",
              "      <td>603.0</td>\n",
              "      <td>4.8</td>\n",
              "      <td>2.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>42.0</td>\n",
              "      <td>-114.3</td>\n",
              "      <td>52.0</td>\n",
              "      <td>32054.0</td>\n",
              "      <td>5290.0</td>\n",
              "      <td>15507.0</td>\n",
              "      <td>5050.0</td>\n",
              "      <td>15.0</td>\n",
              "      <td>52.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Validation examples summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "       latitude  longitude  ...  median_income  rooms_per_person\n",
              "count    5000.0     5000.0  ...         5000.0            5000.0\n",
              "mean       35.6     -119.6  ...            3.8               2.0\n",
              "std         2.1        2.0  ...            1.9               1.3\n",
              "min        32.5     -124.3  ...            0.5               0.1\n",
              "25%        33.9     -121.8  ...            2.5               1.5\n",
              "50%        34.3     -118.5  ...            3.5               2.0\n",
              "75%        37.7     -118.0  ...            4.7               2.3\n",
              "max        41.9     -114.5  ...           15.0              55.2\n",
              "\n",
              "[8 rows x 9 columns]"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>latitude</th>\n",
              "      <th>longitude</th>\n",
              "      <th>housing_median_age</th>\n",
              "      <th>total_rooms</th>\n",
              "      <th>total_bedrooms</th>\n",
              "      <th>population</th>\n",
              "      <th>households</th>\n",
              "      <th>median_income</th>\n",
              "      <th>rooms_per_person</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "      <td>5000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>35.6</td>\n",
              "      <td>-119.6</td>\n",
              "      <td>28.7</td>\n",
              "      <td>2662.4</td>\n",
              "      <td>545.6</td>\n",
              "      <td>1450.2</td>\n",
              "      <td>508.3</td>\n",
              "      <td>3.8</td>\n",
              "      <td>2.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>2.1</td>\n",
              "      <td>2.0</td>\n",
              "      <td>12.5</td>\n",
              "      <td>2263.6</td>\n",
              "      <td>435.2</td>\n",
              "      <td>1291.8</td>\n",
              "      <td>400.6</td>\n",
              "      <td>1.9</td>\n",
              "      <td>1.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>32.5</td>\n",
              "      <td>-124.3</td>\n",
              "      <td>2.0</td>\n",
              "      <td>2.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>6.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>0.5</td>\n",
              "      <td>0.1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>33.9</td>\n",
              "      <td>-121.8</td>\n",
              "      <td>18.0</td>\n",
              "      <td>1452.0</td>\n",
              "      <td>297.0</td>\n",
              "      <td>786.0</td>\n",
              "      <td>282.0</td>\n",
              "      <td>2.5</td>\n",
              "      <td>1.5</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>34.3</td>\n",
              "      <td>-118.5</td>\n",
              "      <td>29.0</td>\n",
              "      <td>2146.0</td>\n",
              "      <td>434.0</td>\n",
              "      <td>1163.0</td>\n",
              "      <td>411.0</td>\n",
              "      <td>3.5</td>\n",
              "      <td>2.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>37.7</td>\n",
              "      <td>-118.0</td>\n",
              "      <td>37.0</td>\n",
              "      <td>3158.2</td>\n",
              "      <td>655.2</td>\n",
              "      <td>1725.0</td>\n",
              "      <td>610.0</td>\n",
              "      <td>4.7</td>\n",
              "      <td>2.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>41.9</td>\n",
              "      <td>-114.5</td>\n",
              "      <td>52.0</td>\n",
              "      <td>37937.0</td>\n",
              "      <td>6445.0</td>\n",
              "      <td>35682.0</td>\n",
              "      <td>6082.0</td>\n",
              "      <td>15.0</td>\n",
              "      <td>55.2</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Training targets summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "       median_house_value_is_high\n",
              "count                     12000.0\n",
              "mean                          0.3\n",
              "std                           0.4\n",
              "min                           0.0\n",
              "25%                           0.0\n",
              "50%                           0.0\n",
              "75%                           1.0\n",
              "max                           1.0"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>median_house_value_is_high</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>12000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>0.3</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>0.4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ]
          },
          "metadata": {
            "tags": []
          }
        },
        {
          "output_type": "stream",
          "text": [
            "Validation targets summary:\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "text/plain": [
              "       median_house_value_is_high\n",
              "count                      5000.0\n",
              "mean                          0.2\n",
              "std                           0.4\n",
              "min                           0.0\n",
              "25%                           0.0\n",
              "50%                           0.0\n",
              "75%                           0.0\n",
              "max                           1.0"
            ],
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>median_house_value_is_high</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>count</th>\n",
              "      <td>5000.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>mean</th>\n",
              "      <td>0.2</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>std</th>\n",
              "      <td>0.4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>min</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>25%</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>50%</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>75%</th>\n",
              "      <td>0.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>max</th>\n",
              "      <td>1.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uon1LB3A31VN",
        "colab_type": "text"
      },
      "source": [
        " ## 线性回归会有怎样的表现？\n",
        "为了解逻辑回归为什么有效，我们首先训练一个使用线性回归的简单模型。该模型将使用 `{0, 1}` 中的值为标签，并尝试预测一个尽可能接近 `0` 或 `1` 的连续值。此外，我们希望将输出解读为概率，所以最好模型的输出值可以位于 `(0, 1)` 范围内。然后我们会应用阈值 `0.5`，以确定标签。\n",
        "\n",
        "运行以下单元格，以使用 [LinearRegressor](https://www.tensorflow.org/api_docs/python/tf/estimator/LinearRegressor) 训练线性回归模型。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "smmUYRDtWOV_",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def construct_feature_columns(input_features):\n",
        "  \"\"\"Construct the TensorFlow Feature Columns.\n",
        "\n",
        "  Args:\n",
        "    input_features: The names of the numerical input features to use.\n",
        "  Returns:\n",
        "    A set of feature columns\n",
        "  \"\"\"\n",
        "  return set([tf.feature_column.numeric_column(my_feature)\n",
        "              for my_feature in input_features])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "B5OwSrr1yIKD",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def my_input_fn(features, targets, batch_size=1, shuffle=True, num_epochs=None):\n",
        "    \"\"\"Trains a linear regression model.\n",
        "  \n",
        "    Args:\n",
        "      features: pandas DataFrame of features\n",
        "      targets: pandas DataFrame of targets\n",
        "      batch_size: Size of batches to be passed to the model\n",
        "      shuffle: True or False. Whether to shuffle the data.\n",
        "      num_epochs: Number of epochs for which data should be repeated. None = repeat indefinitely\n",
        "    Returns:\n",
        "      Tuple of (features, labels) for next data batch\n",
        "    \"\"\"\n",
        "    \n",
        "    # Convert pandas data into a dict of np arrays.\n",
        "    features = {key:np.array(value) for key,value in dict(features).items()}                                            \n",
        " \n",
        "    # Construct a dataset, and configure batching/repeating.\n",
        "    ds = Dataset.from_tensor_slices((features,targets)) # warning: 2GB limit\n",
        "    ds = ds.batch(batch_size).repeat(num_epochs)\n",
        "    \n",
        "    # Shuffle the data, if specified.\n",
        "    if shuffle:\n",
        "      ds = ds.shuffle(10000)\n",
        "    \n",
        "    # Return the next batch of data.\n",
        "    features, labels = ds.make_one_shot_iterator().get_next()\n",
        "    return features, labels"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "SE2-hq8PIYHz",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train_linear_regressor_model(\n",
        "    learning_rate,\n",
        "    steps,\n",
        "    batch_size,\n",
        "    training_examples,\n",
        "    training_targets,\n",
        "    validation_examples,\n",
        "    validation_targets):\n",
        "  \"\"\"Trains a linear regression model.\n",
        "  \n",
        "  In addition to training, this function also prints training progress information,\n",
        "  as well as a plot of the training and validation loss over time.\n",
        "  \n",
        "  Args:\n",
        "    learning_rate: A `float`, the learning rate.\n",
        "    steps: A non-zero `int`, the total number of training steps. A training step\n",
        "      consists of a forward and backward pass using a single batch.\n",
        "    batch_size: A non-zero `int`, the batch size.\n",
        "    training_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for training.\n",
        "    training_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for training.\n",
        "    validation_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for validation.\n",
        "    validation_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for validation.\n",
        "      \n",
        "  Returns:\n",
        "    A `LinearRegressor` object trained on the training data.\n",
        "  \"\"\"\n",
        "\n",
        "  periods = 10\n",
        "  steps_per_period = steps / periods\n",
        "\n",
        "  # Create a linear regressor object.\n",
        "  my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
        "  my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
        "  linear_regressor = tf.estimator.LinearRegressor(\n",
        "      feature_columns=construct_feature_columns(training_examples),\n",
        "      optimizer=my_optimizer\n",
        "  )\n",
        "    \n",
        "  # Create input functions.  \n",
        "  training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                          training_targets[\"median_house_value_is_high\"], \n",
        "                                          batch_size=batch_size)\n",
        "  predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                                  training_targets[\"median_house_value_is_high\"], \n",
        "                                                  num_epochs=1, \n",
        "                                                  shuffle=False)\n",
        "  predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
        "                                                    validation_targets[\"median_house_value_is_high\"], \n",
        "                                                    num_epochs=1, \n",
        "                                                    shuffle=False)\n",
        "\n",
        "  # Train the model, but do so inside a loop so that we can periodically assess\n",
        "  # loss metrics.\n",
        "  print(\"Training model...\")\n",
        "  print(\"RMSE (on training data):\")\n",
        "  training_rmse = []\n",
        "  validation_rmse = []\n",
        "  for period in range (0, periods):\n",
        "    # Train the model, starting from the prior state.\n",
        "    linear_regressor.train(\n",
        "        input_fn=training_input_fn,\n",
        "        steps=steps_per_period\n",
        "    )\n",
        "    \n",
        "    # Take a break and compute predictions.\n",
        "    training_predictions = linear_regressor.predict(input_fn=predict_training_input_fn)\n",
        "    training_predictions = np.array([item['predictions'][0] for item in training_predictions])\n",
        "    \n",
        "    validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)\n",
        "    validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
        "    \n",
        "    # Compute training and validation loss.\n",
        "    training_root_mean_squared_error = math.sqrt(\n",
        "        metrics.mean_squared_error(training_predictions, training_targets))\n",
        "    validation_root_mean_squared_error = math.sqrt(\n",
        "        metrics.mean_squared_error(validation_predictions, validation_targets))\n",
        "    # Occasionally print the current loss.\n",
        "    print(\"  period %02d : %0.2f\" % (period, training_root_mean_squared_error))\n",
        "    # Add the loss metrics from this period to our list.\n",
        "    training_rmse.append(training_root_mean_squared_error)\n",
        "    validation_rmse.append(validation_root_mean_squared_error)\n",
        "  print(\"Model training finished.\")\n",
        "  \n",
        "  # Output a graph of loss metrics over periods.\n",
        "  plt.ylabel(\"RMSE\")\n",
        "  plt.xlabel(\"Periods\")\n",
        "  plt.title(\"Root Mean Squared Error vs. Periods\")\n",
        "  plt.tight_layout()\n",
        "  plt.plot(training_rmse, label=\"training\")\n",
        "  plt.plot(validation_rmse, label=\"validation\")\n",
        "  plt.legend()\n",
        "\n",
        "  return linear_regressor"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "TDBD8xeeIYH2",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 657
        },
        "outputId": "b45f6539-485e-4ef2-a58a-81a85485c4e3"
      },
      "source": [
        "linear_regressor = train_linear_regressor_model(\n",
        "    learning_rate=0.000001,\n",
        "    steps=200,\n",
        "    batch_size=20,\n",
        "    training_examples=training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=validation_examples,\n",
        "    validation_targets=validation_targets)"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "\n",
            "WARNING: The TensorFlow contrib module will not be included in TensorFlow 2.0.\n",
            "For more information, please see:\n",
            "  * https://github.com/tensorflow/community/blob/master/rfcs/20180907-contrib-sunset.md\n",
            "  * https://github.com/tensorflow/addons\n",
            "If you depend on functionality not listed there, please file an issue.\n",
            "\n",
            "Training model...\n",
            "RMSE (on training data):\n",
            "  period 00 : 0.45\n",
            "  period 01 : 0.45\n",
            "  period 02 : 0.45\n",
            "  period 03 : 0.44\n",
            "  period 04 : 0.45\n",
            "  period 05 : 0.44\n",
            "  period 06 : 0.44\n",
            "  period 07 : 0.44\n",
            "  period 08 : 0.44\n",
            "  period 09 : 0.44\n",
            "Model training finished.\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nufqYAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JjBZ_q7aD9gh",
        "colab_type": "text"
      },
      "source": [
        " ## 任务 1：我们可以计算这些预测的对数损失函数吗？\n",
        "\n",
        "**检查预测，并确定是否可以使用它们来计算对数损失函数。**\n",
        "\n",
        "`LinearRegressor` 使用的是 L2 损失，在将输出解读为概率时，它并不能有效地惩罚误分类。例如，对于概率分别为 0.9 和 0.9999 的负分类样本是否被分类为正分类，二者之间的差异应该很大，但 L2 损失并不会明显区分这些情况。\n",
        "\n",
        "相比之下，`LogLoss`（对数损失函数）对这些\"置信错误\"的惩罚力度更大。请注意，`LogLoss` 的定义如下：\n",
        "\n",
        "$$Log Loss = \\sum_{(x,y)\\in D} -y \\cdot log(y_{pred}) - (1 - y) \\cdot log(1 - y_{pred})$$\n",
        "\n",
        "\n",
        "但我们首先需要获得预测值。我们可以使用 `LinearRegressor.predict` 获得预测值。\n",
        "\n",
        "我们可以使用预测和相应目标计算 `LogLoss` 吗？"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dPpJUV862FYI",
        "colab_type": "text"
      },
      "source": [
        " ### 解决方案\n",
        "\n",
        "点击下方即可查看解决方案。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "kXFQ5uig2RoP",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 269
        },
        "outputId": "621e3299-d656-48a6-a252-0e06344d49c3"
      },
      "source": [
        "predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
        "                                                  validation_targets[\"median_house_value_is_high\"], \n",
        "                                                  num_epochs=1, \n",
        "                                                  shuffle=False)\n",
        "\n",
        "validation_predictions = linear_regressor.predict(input_fn=predict_validation_input_fn)\n",
        "validation_predictions = np.array([item['predictions'][0] for item in validation_predictions])\n",
        "\n",
        "_ = plt.hist(validation_predictions)"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nRU5ErkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rYpy336F9wBg",
        "colab_type": "text"
      },
      "source": [
        " ## 任务 2：训练逻辑回归模型并计算验证集的对数损失函数\n",
        "\n",
        "要使用逻辑回归非常简单，用 [LinearClassifier](https://www.tensorflow.org/api_docs/python/tf/estimator/LinearClassifier) 替代 `LinearRegressor` 即可。完成以下代码。\n",
        "\n",
        "**注意**：在 `LinearClassifier` 模型上运行 `train()` 和 `predict()` 时，您可以通过返回的字典（例如 `predictions[\"probabilities\"]`）中的 `\"probabilities\"` 键获取实值预测概率。Sklearn 的 [log_loss](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html) 函数可基于这些概率计算对数损失函数，非常方便。\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JElcb--E9wBm",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train_linear_classifier_model(\n",
        "    learning_rate,\n",
        "    steps,\n",
        "    batch_size,\n",
        "    training_examples,\n",
        "    training_targets,\n",
        "    validation_examples,\n",
        "    validation_targets):\n",
        "  \"\"\"Trains a linear classification model.\n",
        "  \n",
        "  In addition to training, this function also prints training progress information,\n",
        "  as well as a plot of the training and validation loss over time.\n",
        "  \n",
        "  Args:\n",
        "    learning_rate: A `float`, the learning rate.\n",
        "    steps: A non-zero `int`, the total number of training steps. A training step\n",
        "      consists of a forward and backward pass using a single batch.\n",
        "    batch_size: A non-zero `int`, the batch size.\n",
        "    training_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for training.\n",
        "    training_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for training.\n",
        "    validation_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for validation.\n",
        "    validation_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for validation.\n",
        "      \n",
        "  Returns:\n",
        "    A `LinearClassifier` object trained on the training data.\n",
        "  \"\"\"\n",
        "\n",
        "  periods = 10\n",
        "  steps_per_period = steps / periods\n",
        "  \n",
        "  # Create a linear classifier object.\n",
        "  my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
        "  my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)\n",
        "  linear_classifier = # YOUR CODE HERE: Construct the linear classifier.\n",
        "  \n",
        "  # Create input functions.\n",
        "  training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                          training_targets[\"median_house_value_is_high\"], \n",
        "                                          batch_size=batch_size)\n",
        "  predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                                  training_targets[\"median_house_value_is_high\"], \n",
        "                                                  num_epochs=1, \n",
        "                                                  shuffle=False)\n",
        "  predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
        "                                                    validation_targets[\"median_house_value_is_high\"], \n",
        "                                                    num_epochs=1, \n",
        "                                                    shuffle=False)\n",
        "  \n",
        "  # Train the model, but do so inside a loop so that we can periodically assess\n",
        "  # loss metrics.\n",
        "  print(\"Training model...\")\n",
        "  print(\"LogLoss (on training data):\")\n",
        "  training_log_losses = []\n",
        "  validation_log_losses = []\n",
        "  for period in range (0, periods):\n",
        "    # Train the model, starting from the prior state.\n",
        "    linear_classifier.train(\n",
        "        input_fn=training_input_fn,\n",
        "        steps=steps_per_period\n",
        "    )\n",
        "    # Take a break and compute predictions.    \n",
        "    training_probabilities = linear_classifier.predict(input_fn=predict_training_input_fn)\n",
        "    training_probabilities = np.array([item['probabilities'] for item in training_probabilities])\n",
        "    \n",
        "    validation_probabilities = linear_classifier.predict(input_fn=predict_validation_input_fn)\n",
        "    validation_probabilities = np.array([item['probabilities'] for item in validation_probabilities])\n",
        "    \n",
        "    training_log_loss = metrics.log_loss(training_targets, training_probabilities)\n",
        "    validation_log_loss = metrics.log_loss(validation_targets, validation_probabilities)\n",
        "    # Occasionally print the current loss.\n",
        "    print(\"  period %02d : %0.2f\" % (period, training_log_loss))\n",
        "    # Add the loss metrics from this period to our list.\n",
        "    training_log_losses.append(training_log_loss)\n",
        "    validation_log_losses.append(validation_log_loss)\n",
        "  print(\"Model training finished.\")\n",
        "  \n",
        "  # Output a graph of loss metrics over periods.\n",
        "  plt.ylabel(\"LogLoss\")\n",
        "  plt.xlabel(\"Periods\")\n",
        "  plt.title(\"LogLoss vs. Periods\")\n",
        "  plt.tight_layout()\n",
        "  plt.plot(training_log_losses, label=\"training\")\n",
        "  plt.plot(validation_log_losses, label=\"validation\")\n",
        "  plt.legend()\n",
        "\n",
        "  return linear_classifier"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "VM0wmnFUIYH9",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "linear_classifier = train_linear_classifier_model(\n",
        "    learning_rate=0.000005,\n",
        "    steps=500,\n",
        "    batch_size=20,\n",
        "    training_examples=training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=validation_examples,\n",
        "    validation_targets=validation_targets)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "i2e3TlyL57Qs",
        "colab_type": "text"
      },
      "source": [
        " ### 解决方案\n",
        "\n",
        "点击下方即可查看解决方案。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "5YxXd2hn6MuF",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "def train_linear_classifier_model(\n",
        "    learning_rate,\n",
        "    steps,\n",
        "    batch_size,\n",
        "    training_examples,\n",
        "    training_targets,\n",
        "    validation_examples,\n",
        "    validation_targets):\n",
        "  \"\"\"Trains a linear classification model.\n",
        "  \n",
        "  In addition to training, this function also prints training progress information,\n",
        "  as well as a plot of the training and validation loss over time.\n",
        "  \n",
        "  Args:\n",
        "    learning_rate: A `float`, the learning rate.\n",
        "    steps: A non-zero `int`, the total number of training steps. A training step\n",
        "      consists of a forward and backward pass using a single batch.\n",
        "    batch_size: A non-zero `int`, the batch size.\n",
        "    training_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for training.\n",
        "    training_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for training.\n",
        "    validation_examples: A `DataFrame` containing one or more columns from\n",
        "      `california_housing_dataframe` to use as input features for validation.\n",
        "    validation_targets: A `DataFrame` containing exactly one column from\n",
        "      `california_housing_dataframe` to use as target for validation.\n",
        "      \n",
        "  Returns:\n",
        "    A `LinearClassifier` object trained on the training data.\n",
        "  \"\"\"\n",
        "\n",
        "  periods = 10\n",
        "  steps_per_period = steps / periods\n",
        "  \n",
        "  # Create a linear classifier object.\n",
        "  my_optimizer = tf.train.GradientDescentOptimizer(learning_rate=learning_rate)\n",
        "  my_optimizer = tf.contrib.estimator.clip_gradients_by_norm(my_optimizer, 5.0)  \n",
        "  linear_classifier = tf.estimator.LinearClassifier(\n",
        "      feature_columns=construct_feature_columns(training_examples),\n",
        "      optimizer=my_optimizer\n",
        "  )\n",
        "  \n",
        "  # Create input functions.\n",
        "  training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                          training_targets[\"median_house_value_is_high\"], \n",
        "                                          batch_size=batch_size)\n",
        "  predict_training_input_fn = lambda: my_input_fn(training_examples, \n",
        "                                                  training_targets[\"median_house_value_is_high\"], \n",
        "                                                  num_epochs=1, \n",
        "                                                  shuffle=False)\n",
        "  predict_validation_input_fn = lambda: my_input_fn(validation_examples, \n",
        "                                                    validation_targets[\"median_house_value_is_high\"], \n",
        "                                                    num_epochs=1, \n",
        "                                                    shuffle=False)\n",
        "  \n",
        "  # Train the model, but do so inside a loop so that we can periodically assess\n",
        "  # loss metrics.\n",
        "  print(\"Training model...\")\n",
        "  print(\"LogLoss (on training data):\")\n",
        "  training_log_losses = []\n",
        "  validation_log_losses = []\n",
        "  for period in range (0, periods):\n",
        "    # Train the model, starting from the prior state.\n",
        "    linear_classifier.train(\n",
        "        input_fn=training_input_fn,\n",
        "        steps=steps_per_period\n",
        "    )\n",
        "    # Take a break and compute predictions.    \n",
        "    training_probabilities = linear_classifier.predict(input_fn=predict_training_input_fn)\n",
        "    training_probabilities = np.array([item['probabilities'] for item in training_probabilities])\n",
        "    \n",
        "    validation_probabilities = linear_classifier.predict(input_fn=predict_validation_input_fn)\n",
        "    validation_probabilities = np.array([item['probabilities'] for item in validation_probabilities])\n",
        "    \n",
        "    training_log_loss = metrics.log_loss(training_targets, training_probabilities)\n",
        "    validation_log_loss = metrics.log_loss(validation_targets, validation_probabilities)\n",
        "    # Occasionally print the current loss.\n",
        "    print(\"  period %02d : %0.2f\" % (period, training_log_loss))\n",
        "    # Add the loss metrics from this period to our list.\n",
        "    training_log_losses.append(training_log_loss)\n",
        "    validation_log_losses.append(validation_log_loss)\n",
        "  print(\"Model training finished.\")\n",
        "  \n",
        "  # Output a graph of loss metrics over periods.\n",
        "  plt.ylabel(\"LogLoss\")\n",
        "  plt.xlabel(\"Periods\")\n",
        "  plt.title(\"LogLoss vs. Periods\")\n",
        "  plt.tight_layout()\n",
        "  plt.plot(training_log_losses, label=\"training\")\n",
        "  plt.plot(validation_log_losses, label=\"validation\")\n",
        "  plt.legend()\n",
        "\n",
        "  return linear_classifier"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "UPM_T1FXsTaL",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 531
        },
        "outputId": "80fd8efb-4746-4675-c561-680f222d08ad"
      },
      "source": [
        "linear_classifier = train_linear_classifier_model(\n",
        "    learning_rate=0.000005,\n",
        "    steps=500,\n",
        "    batch_size=20,\n",
        "    training_examples=training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=validation_examples,\n",
        "    validation_targets=validation_targets)"
      ],
      "execution_count": 10,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Training model...\n",
            "LogLoss (on training data):\n",
            "  period 00 : 0.60\n",
            "  period 01 : 0.58\n",
            "  period 02 : 0.57\n",
            "  period 03 : 0.56\n",
            "  period 04 : 0.55\n",
            "  period 05 : 0.55\n",
            "  period 06 : 0.54\n",
            "  period 07 : 0.54\n",
            "  period 08 : 0.53\n",
            "  period 09 : 0.54\n",
            "Model training finished.\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "i-Xo83_aR6s_",
        "colab_type": "text"
      },
      "source": [
        " ## 任务 3：计算准确率并为验证集绘制 ROC 曲线\n",
        "\n",
        "分类时非常有用的一些指标包括：模型[准确率](https://en.wikipedia.org/wiki/Accuracy_and_precision#In_binary_classification)、[ROC 曲线](https://en.wikipedia.org/wiki/Receiver_operating_characteristic)和 ROC 曲线下面积 (AUC)。我们会检查这些指标。\n",
        "\n",
        "`LinearClassifier.evaluate` 可计算准确率和 AUC 等实用指标。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "DKSQ87VVIYIA",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 53
        },
        "outputId": "a8fb01e7-d0f9-4666-af93-998a74e5133c"
      },
      "source": [
        "evaluation_metrics = linear_classifier.evaluate(input_fn=predict_validation_input_fn)\n",
        "\n",
        "print(\"AUC on the validation set: %0.2f\" % evaluation_metrics['auc'])\n",
        "print(\"Accuracy on the validation set: %0.2f\" % evaluation_metrics['accuracy'])"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "AUC on the validation set: 0.71\n",
            "Accuracy on the validation set: 0.75\n"
          ],
          "name": "stdout"
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "47xGS2uNIYIE",
        "colab_type": "text"
      },
      "source": [
        " 您可以使用类别概率（例如由 `LinearClassifier.predict` \n",
        "和 Sklearn 的 [roc_curve](http://scikit-learn.org/stable/modules/model_evaluation.html#roc-metrics) 计算的概率）来获得绘制 ROC 曲线所需的真正例率和假正例率。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xaU7ttj8IYIF",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 269
        },
        "outputId": "8d3601e6-09aa-40b1-af1b-4f37aa8434b8"
      },
      "source": [
        "validation_probabilities = linear_classifier.predict(input_fn=predict_validation_input_fn)\n",
        "# Get just the probabilities for the positive class.\n",
        "validation_probabilities = np.array([item['probabilities'][1] for item in validation_probabilities])\n",
        "\n",
        "false_positive_rate, true_positive_rate, thresholds = metrics.roc_curve(\n",
        "    validation_targets, validation_probabilities)\n",
        "plt.plot(false_positive_rate, true_positive_rate, label=\"our model\")\n",
        "plt.plot([0, 1], [0, 1], label=\"random classifier\")\n",
        "_ = plt.legend(loc=2)"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi40LCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcv7US4rQAAIABJREFUeJzt3Xd4FFXbx/HvSSGhJPQaAgk1QEIN\nvUWKVEGxgaLiA/KioiKCYAMEFQuCD1hRwS6CCoTeBCnSQodISSBA6EkgQCD9vH9M3CcgkCXs7uxu\n7s915bp2Z2d378kmv0xmztxHaa0RQgjhXjzMLkAIIYTtSbgLIYQbknAXQgg3JOEuhBBuSMJdCCHc\nkIS7EEK4IQl3IYRwQxLuQgjhhiTchRDCDXmZ9cZlypTRQUFBZr29EEK4pG3btiVorcvmtZ5p4R4U\nFERUVJRZby+EEC5JKXXUmvXksIwQQrghCXchhHBDEu5CCOGGTDvmfiMZGRnEx8eTmppqdinCTnx9\nfalcuTLe3t5mlyKEW3OqcI+Pj8fPz4+goCCUUmaXI2xMa01iYiLx8fEEBwebXY4Qbi3PwzJKqRlK\nqbNKqb03eVwppaYqpWKUUruVUo3zW0xqaiqlS5eWYHdTSilKly4t/5kJ4QDWHHP/Buh6i8e7ATVz\nvgYDn91JQRLs7k0+XyEcI89w11qvBZJusUpv4Dtt2ASUUEpVtFWBQgjh6tIzs4k+eZEf1v3Npi+G\nEh19wwMhNmWLY+4BwPFc9+Nzlp26fkWl1GCMvXuqVKlig7cuONasWcOkSZNYuHDhHa0jhLAvrTUT\nl+xn85EkShbx5uDpS5xMTqWlxz7e9fqSqh5n2by3CtQNtWsdDj2hqrWeDkwHCA8Pd7uZuTMzM/Hy\ncqpz1EIIO7uclknCpTQW7TnFzA1HSLicbnksoERhqhTNZHja1zzAKlKKVeVEp19p3rCz3euyRRKd\nAAJz3a+cs8wlTZ48mRkzZgAwaNAghg0bRlxcHD179mTvXuNfqUmTJnH58mXGjRtHREQEDRs2ZP36\n9fTr14+XXnrJ8lrjxo3jyJEjHD58mGPHjjFlyhQ2bdrEkiVLCAgIYMGCBXh7e7Nq1SpGjBhBZmYm\nTZs25bPPPsPHx4elS5cybNgwihQpQps2bSyvm5KSwnPPPcfevXvJyMhg3Lhx9O7d27HfKCEKkPTM\nbIb9soOouPMU9fHiSEIKnh4KLw9FWmb2v9YPLlOU+UNb4x+3AhYNB3UGWr1A0YhXKOpd2CE12yLc\nI4GhSqlZQHMgWWv9r0Myt+vNBfuIPnnxjovLrW4lf8beU++mj2/bto2ZM2eyefNmtNY0b96c9u3b\nU7JkyVu+bnp6+k375MTGxrJ69Wqio6Np2bIlv/32G++//z733XcfixYtomvXrgwYMIBVq1ZRq1Yt\nHn/8cT777DOGDBnCU089xR9//EGNGjV4+OGHLa/59ttv06FDB2bMmMGFCxdo1qwZnTp1yt83RQhx\nQ1pr1scksO3oeT5aeciyvJ6fDy2qlaKCvy/l/X3JyNL4+XpRzt+HznXKU87fFy6fgwWDYd/vUK4e\n9P0JAvI9kDBf8gx3pdTPQARQRikVD4wFvAG01p8Di4HuQAxwBXjSXsXa2/r167nvvvsoWrQoAH36\n9GHdunX06tXrls/LHbzX69atG97e3oSFhZGVlUXXrsbAo7CwMOLi4jhw4ADBwcHUqlULgCeeeIJP\nPvmEiIgIgoODqVmzJgD9+/dn+vTpACxfvpzIyEgmTZoEGENIjx07dmcbL0QBlJKWyemLqew9kcy5\nS2nsOHaB0sUKceL8VTbEJpCace1eeew73fH0uMWIL61h92xYMgrSL8Ndr0PrF8CrkJ235N/yDHet\ndb88HtfAszarKMet9rAdzcvLi+zs/33I14/T/uePwY34+PgA4OHhgbe3t2UooIeHB5mZmfmqR2vN\nb7/9Ru3ata9ZfubMmXy9nhDu6sKVdDbGJhKXeMWyLC0zix3HLvDnwXM3fZ6frxepGdmEVPDj9R51\nCQ3wp0SRPAI6OR4WDodDy6ByU+j1MZQLsdWm3DY5+5dL27ZtGTBgAKNHj0Zrzdy5c/n+++8pX748\nZ8+eJTExkWLFirFw4ULLHvidql27NnFxccTExFCjRg2+//572rdvT0hICHFxccTGxlK9enV+/vln\ny3O6dOnCtGnTmDZtGkopduzYQaNGjWxSjxCuaN/JZObtOEFhb08Alu47zcEzl6167gsda1KhuC9h\nAcUJLFWE4oVvszVGdjZsmwkrxoLOgq7vQrPB4OF5u5thUxLuuTRu3JgBAwbQrFkzwDih+k9ojhkz\nhmbNmhEQEEBIiO3+Gvv6+jJz5kwefPBBywnVIUOG4OPjw/Tp0+nRowdFihShbdu2XLp0CYA33niD\nYcOGUb9+fbKzswkODpbhj6JASc/M5sSFq3ywbD+L95y+5jGljKMjAA0qF6d7WEU61y1PpRL/O5Hp\noRSFvGzQNzExFiKfg6MboFoE3PNfKBl0569rA0prc0YkhoeH6+tPQv7999/UqVPHlHqE48jnLG7H\n4XOXOXjmEpG7TrLv5EWO5jrEktuMAeF0CCnvmKKyMmHjx7BmInj6QJe3oVF/4y+LnSmltmmtw/Na\nT/bchRBOITMrm3WHEpiz7Ti745OJP3/1mr3wf3h5KJoFl6JGuWLUqehPv2YOviDy9B6YPxRO7YSQ\nntB9Evg730X5Eu5CCLtKvprB4XOXiUtMITPLSOrl0Wf48+A5Khb3xSNnb/dIQso1zytayJOQiv40\nrlKC2hX8qVvRn9oV/G49WsWeMtNg7QewfgoULgkPfgN173XI3np+SLgLIWzmUmoGO49f4PC5FCJ3\nnST23GUuXMm46fp+vl5UK1MMgLCA4nh7evBgeGWaVC2Jt6cTzSV0fIuxt55wABr0gy7vQJFSZld1\nSxLuQoh8O550hb0nkvH0UIz8dTfJV/8d5GWK+dCvWSCNqpSgvL8v/r7GaJSKxX3xcqYAv5H0FFg1\nATZ/DsUrw6O/QU3XuGBQwl0IcVu++DOWiUv23/TxDiHlGNK+OhWL+xJYqogDK7Ox2NWw4Hm4cAya\nPgWdxoKPn9lVWU3CXQhxS2sPnmNF9Bm8PBVL957mVLJxEV8hLw961q9I8+BS1KtUHA+lCKngh4dZ\nx8Rt5ep5WP467PgBSteAJ5dA1VZmV3XbJNztLCgoiKioKMqUKWP394qIiGDSpEmEh+c5SipPUVFR\nfPfdd0ydOpW0tDR69OhBQkICr7zyCitWrGD48OHUrVvXBlULZ7Q1LokXf9lJ/Pmr1yz39TYOozh0\n2KEj/b0AFr0EKQnQ5kVoPxq8fc2uKl8k3G9Ca43WGg8PJz8maCfh4eGWPxI7duwAYOfOncCte+nc\nSFZWFp6e5l6tJ/KWla35bE0Mk5YfvGZ54yolGNqhBu1qlnX+Y+T5dfksLB4J0fOgQhg8MhsqNTS7\nqjvipp9U/sTFxVG7dm0ef/xxQkNDOX78OE8//TTh4eHUq1ePsWPHWtYNCgpi7NixNG7cmLCwMPbv\nN45BJiYmcvfdd1OvXj0GDRpE7ovEJk+eTGhoKKGhoXz00UeW9wwJCWHAgAHUqlWLRx99lJUrV9K6\ndWtq1qzJli1b/lVnVlYWI0aMIDQ0lPr16zNt2rR/rXOzukePHk3dunWpX78+I0aMAGDOnDmEhobS\noEED2rVrBxgTf/Ts2ZOzZ8/Sv39/tm7dSsOGDYmNjSUiIsLSBXP58uW0bNmSxo0b8+CDD3L58mXL\n92fUqFE0btyYOXPm3NHnIuwrIyubXccvUP3VxZZgL1OsEDMHNCXu3R78/kxrOoSUd89g1xp2/gwf\nN4UDi6HDG/DUapcPdnDmPfclo42LBWypQhh0e/eWqxw6dIhvv/2WFi1aAEZ73VKlSpGVlUXHjh3Z\nvXs39evXB6BMmTJs376dTz/9lEmTJvHVV1/x5ptv0qZNG8aMGcOiRYv4+uuvgVu3E46JiWHOnDnM\nmDGDpk2b8tNPP7F+/XoiIyN55513mDdv3jU1Tp8+nbi4OHbu3ImXlxdJSf+eBfFGdQcEBDB37lz2\n79+PUooLFy4AMH78eJYtW0ZAQIBl2T/KlSvHV199dcMZnhISEnjrrbdYuXIlRYsW5b333mPy5MmM\nGTMGgNKlS7N9+3ZrPx3hYAmX0ziWdIU+n/51zfK1I++iSmkXPhFqrQvHYeEwiFkJgc2NRl9la5ld\nlc04b7ibpGrVqpZgB5g9ezbTp08nMzOTU6dOER0dbQn3Pn36ANCkSRN+//13ANauXWu53aNHD0sv\n+Fu1Ew4ODiYsLAyAevXq0bFjR5RSlrbA11u5ciVDhgyxzPpUqtS/x9veqO66devi6+vLwIED6dmz\nJz179gSgdevWDBgwgIceesiyTdbYtGkT0dHRtG7dGjD62rds2dLy+O0evhGOceZiKs3fWfWv5T8O\nak7ToFK26bnizLKzIeprWDnO2HPv9gE0HQRudgjWecM9jz1se8ndvvfIkSNMmjSJrVu3UrJkSQYM\nGHBNu99/2vl6enrmu31v7tcBoxVw7jbB+Xndm9Xt5eXFli1bWLVqFb/++isff/wxf/zxB59//jmb\nN29m0aJFNGnShG3btln1PlprOnfufE3Hytxu1QpZON7Zi6k0uy7UJ9wbSkV/XzrWKWdpR+3WEg4Z\njb6ObYTqHaDnR1CyqtlV2YV7/amysYsXL1K0aFGKFy/OmTNnWLJkSZ7PadeuHT/99BMAS5Ys4fz5\n84DRTnjevHlcuXKFlJQU5s6dS9u2bfNVV+fOnfniiy8swX/9YZmb1X358mWSk5Pp3r07U6ZMYdeu\nXYAxW1Tz5s0ZP348ZcuW5fjx41ijRYsWbNiwgZiYGMCY/u/gwYN5PEs4yuW0TDbGJvL+0v20nLjK\nEuzFC3vzWvc6HH6nO4+1qEqnuuXdP9izMmDdZPisNZz9G+79DPr/7rbBDs685+4EGjRoQKNGjQgJ\nCSEwMNBy+OFWxo4dS79+/ahXrx6tWrWiShWjqdHN2gnf6LBLXgYNGsTBgwepX78+3t7ePPXUUwwd\nOjTPui9dukTv3r1JTU1Fa83kyZMBGDlyJIcOHUJrTceOHWnQoAF//vlnnnWULVuWb775hn79+pGW\nlgbAW2+9ZZlVSphjQ0wCj361+YaPPdCkMpMebODgikx2apfROuD0bqjTy2j05eeGwzivIy1/hcPJ\n52wfx5Ou0Pb91dcs6xZagUebV6VORT9KF/O5yTPdVEYqrH0f1n8ERUpDj0lQ1/UnkpeWv0K4ubTM\nLFLSspi66hDf/BV3zWOz/68lzYKdu7GVXR3bZOytJx6Chv3h7glO3+jL1iTchXAhx5Ou8OrcPaw7\nlHDDx9/oWZcBrYLMa4trtrRLsGo8bPkSigcax9VrdDS7KlM4Xbhrrd3/5E4BZtZhQFd2JT2T95bs\n59uNR69ZHlCiMD0bVMTf15v+zatSvMhtzv3pbmJWwoJhxkTVzf/PuCDJp5jZVZnGqcLd19eXxMRE\nSpcuLQHvhrTWJCYm4uvrmr067E1rzb6TFxkbuc/SOjfm7L8neZ5wbyj9m1eR35F/XEmCZa/Brp+g\nTC34z1Ko0iLv57k5pwr3ypUrEx8fz7lz58wuRdiJr68vlStXNrsMp5Kemc1Lc3axYNdJyzIPBd1C\nK1K7vB8p6ZmEVPDnuQ41KOrjVL+y5oueD4tGwJVEaDsC2o102UZftuZUPyne3t4EBwebXYYQDnP9\nhUUVi/vyZq96dKxTvuAeN7fGpdOweITRxbFiA+j/G1Ssb3ZVTsWpwl2IguLQmUt8v+ko3+UcR69e\ntig/P9WCcv6y13lLWsPOn2DZK8ZQx07joOVz4ClRdj35jgjhIFfSMxn5624W7T51zfJqZYuycnh7\nOYael/NHYcELcHg1VGkFvaZBmRpmV+W0JNyFcIBVf59h4Lf/u2ivdnk/HmoayH9aB0mo5yU7yxja\nuGo8KGVcYRo+0O0afdmahLsQdnTg9CX6fLqBlPQsAJoFleKLx5pQsmghkytzEecOGI2+jm+GGp2M\nRl8lAs2uyiVIuAthB3EJKURMWnPNsskPNaBPYxkpZJWsDNjwEfz5PhQqCvd9AfUfNvbchVUk3IWw\noae+i2LviWTLJNIAE/uE0bdpoBx+sdbJHTD/OTizB+rdB93eh2LlzK7K5VgV7kqprsB/AU/gK631\nu9c9XgX4FiiRs85orfViG9cqhFOKOXuJZfvO8MGyA5ZlDzapTI1yxfi/9tVNrMzFZFyFNe/CX9Og\naFl4+Eeo09PsqlxWnuGulPIEPgE6A/HAVqVUpNY6OtdqrwOztdafKaXqAouBIDvUK4RTuFEHxn9s\nGN2BgBKFHVyRi4vbYBxbT4qFRo/B3W9B4RJmV+XSrNlzbwbEaK0PAyilZgG9gdzhrgH/nNvFgZMI\n4YZSM7Lo+OGfnLhw1bKsR/2K3FO/IhG1y+Hr7WlidS4o9SKsehO2fgUlqsLj86FahNlVuQVrwj0A\nyD01TzzQ/Lp1xgHLlVLPAUWBTjapTggnMurX3fwS9b9fhZFdavPsXTLOOt8OrTAafV08AS2egQ6v\nGydPhU3Y6oRqP+AbrfWHSqmWwPdKqVCtdXbulZRSg4HBgGWGIiGc3cEzl/ho5UEW7zkNQJ9GAbx9\nXxiFC8leer5cSYKlr8DuWVA2BAaugMCmZlfldqwJ9xNA7oGllXOW5TYQ6Aqgtd6olPIFygBnc6+k\ntZ4OTAdjJqZ81iyE3aVmZPHq3D38vv3aH/WPH2lEz/qVTKrKxWkN++bC4pGQegHaj4K2L4FXAZsh\nykGsCfetQE2lVDBGqPcFHrlunWNAR+AbpVQdwBeQ1o7C5USfvMi7S/ez9uD/fnwbBJZgUJtguoVW\nwMtTrorMl4unYNFLcGARVGoEveZDhVCzq3JreYa71jpTKTUUWIYxzHGG1nqfUmo8EKW1jgReAr5U\nSr2IcXJ1gJZZGYSLWX3gLE/O3Gq5H1LBj1mDW1CiiFxNmm9aw47vYdnrkJUGnScYx9el0ZfdWfUd\nzhmzvvi6ZWNy3Y4GWtu2NCEcIytb8/7S/Xyx9jAA9zasxJSHG8pFR3cq6QgseB6OrIWqbaDXVCgt\n4/4dRf58igInMyubvScvsnDXSb5af+Sax34c1JzWNcqYVJmbyM6CzV/AHxNAeULPKdB4gDT6cjAJ\nd1FgZGZlsyv+Avd/tvFfjw1qE0zPBpVoGCgXztyRs3/D/KFwIgpqdjGCvXiA2VUVSBLuwq1prfly\n3WHeWbz/muV+vl58+mhjmgWXwsdLhjTescx0WD8F1n4APn7Q5ysIe0AafZlIwl24rRu1CHikeRU6\nhpQjonY5mcbOVk5sMxp9nd0HoQ9At/egqBzaMpuEu3ArWmvm7jjB8Nm7rlm+7uW7CCxVxKSq3FT6\nFVjzDmz8BIpVgH6zoHY3s6sSOSTchVvIyMrmr9hEnpix5ZrlI+6uxdAONU2qyo0dWWeMhEk6DE0G\nQOfx4Fvc7KpELhLuwuUt2n2KZ3/abrnv6+3Bb0+3om5FfxnOaGupybBiLGybCSWD4YkFENzO7KrE\nDUi4C5d1PiWdHlPXcTJnYoyu9SrwnzbBNA0qKaFuDweWwsIX4fJpaDkU7noNCsmhLmcl4S5cTmZW\nNjVeW3LNsrfuDaV/i6omVeTmUhJgySjY+yuUqwsP/wCVm5hdlciDhLtwGZfTMukxdR1HE69Ylo3s\nUpsnWgVRzEd+lG1Oa9j7Gyx52ei7HvEqtHkRvKQdgyuQ3wjhEg6eucTdU9Za7rerVZZvBjTFQ4Yz\n2kfyCVg0HA4uhYAm0OtjKF/X7KrEbZBwF04rNSOLVX+fveZkabPgUvwyuIUcU7eX7GzY/i2sGANZ\nGdDlHWg+BDzkQi9XI+EunM5fMQlMXnGQqKPnr1k+4d5QHpPj6vaTGAsLXoC4dRDU1mj0Vaqa2VWJ\nfJJwF07j5IWrDJu1ky1xSZZlrWuU5tXudahXScZQ201WJmz+DP54Gzy94Z6p0PhxaR3g4iTchem2\nHEnivaX72ZZrT/39++vzUNPAWzxL2MSZfUajr5PboXZ36PEh+MtMU+5Awl2Y5os/Y5m45NqGXv2a\nVWFinzCTKipAMtNg3YfGl28JeGAG1Osje+tuRMJdmOLZH7ezaM8pAEID/BnVNYS2NcuaXFUBER9l\n7K2f+xvqPwxdJkLR0mZXJWxMwl04zJI9p1iw+ySL95y2LJszpCVNg0qZWFUBkp5iHFff9Klx6OWR\n2VCri9lVCTuRcBd2N2/HCV6bu4eU9Kxrlv/2dCuaVC1pUlUFzOE/jUZf5+MgfCB0Gge+/iYXJexJ\nwl3Y1fDZO/l9+wnLfZnGzsGuXoAVb8D276BUdRiwCILamF2VcAAJd2Fz2dmaFhNXcfZSmmXZl4+H\n07lueROrKoD2L4KFwyHlLLR+ASJeAe/CZlclHETCXdjcG/P3WoK9etmizH22Nf6+3iZXVYBcPmf0\ng9n3O5QPhX4/Q0Bjs6sSDibhLmxqXOQ+ftx8DIDo8V0oUkh+xBxGa9g9G5aOMk6e3vU6tBlmXJgk\nChz5zRM2czo5lW/+igNgar9GEuyOlBxv9Fo/tBwqNzUafZULMbsqYSL57RN3LDUjixXRZ3ju5x0A\nfPBAfXo1kKscHSI7G7bNgBXjQGdB13eh2WBp9CUk3MWd+fPguWvmLW0YWIIHw6VtgEMkxEDkc3Ds\nL6gWAff8F0oGmVyUcBYS7iJfsrM1HT5cQ1zOxBkNA0swoXcoYZWlwZfdZWXCxo9hzUTw8oHen0DD\nR6V1gLiGhLu4bVprXvl9jyXYf36qBS2ry+XrDnF6D8x/Fk7tgpCeRqMvvwpmVyWckIS7sNql1AzC\nxi2/ZtmyYe2oXcHPpIoKkMw0WPsBrJ8ChUvCg99C3d6yty5uSsJdWGXfyWR6TF1vud8wsASf929C\nheK+JlZVQBzbbBxbTzgADfoZsyMVkX484tYk3MUtXU3PYuC3W/krNhGAMsUKsfnVTnjK3KX2l3YZ\n/pgAm7+A4pXh0d+gZiezqxIuwsOalZRSXZVSB5RSMUqp0TdZ5yGlVLRSap9S6ifblinM8tKcnZZg\nf7R5FaJe7yzB7gixf8BnLWHz59DsKXhmowS7uC157rkrpTyBT4DOQDywVSkVqbWOzrVOTeAVoLXW\n+rxSqpy9ChaOszUuydKe9/A73fGQULe/q+dh2euw8wcoXROeXApVW5pdlXBB1hyWaQbEaK0PAyil\nZgG9gehc6zwFfKK1Pg+gtT5r60KFY0TFJfHi7J0oFMeSjNEw79wXJsHuCH8vgEUvQUoCtBkO7UeB\nt5zTEPljTbgHAMdz3Y8Hml+3Ti0ApdQGwBMYp7Veev0LKaUGA4MBqlSpkp96hR3FJaTwwOcbAfD1\n9qBltdI80rwK98jVpvZ16QwsGQnR86FCmDGJRqWGZlclXJytTqh6ATWBCKAysFYpFaa1vpB7Ja31\ndGA6QHh4uLbRewsbOHsplYhJawC4r1EAUx6WcLE7rWHXz7D0Fci4Ch3HQKvnpdGXsAlrwv0EkPt6\n8so5y3KLBzZrrTOAI0qpgxhhv9UmVQq7evnXXcyOirfcl2B3gAvHYMEwiF0FgS2g1zQoW8vsqoQb\nsSbctwI1lVLBGKHeF3jkunXmAf2AmUqpMhiHaQ7bslBhe0kp6TSesMJyf0j76ozsUtvEigqA7GzY\n+hWsHGfc7/YBNB0EHlYNXBPCanmGu9Y6Uyk1FFiGcTx9htZ6n1JqPBCltY7MeexupVQ0kAWM1Fon\n2rNwcWfmRB1n5K+7LffXvXwXgaWKmFhRAZBwCOYPheOboHpHuOcjKCHnnoR9KK3NOfQdHh6uo6Ki\nTHnvgu6rdYd5a9HfADQPLsWswS1Qchm7/WRlwF9TYc17xjR3XScaV5rK91zkg1Jqm9Y6PK/15ArV\nAmbJnlOWYF/xYjtqlpe+MHZ1apfR6Ov0HqMXTLcPwE/mkhX2J+FegIycs4s524wTp32bBkqw21NG\nKvz5LmyYCkVKw0PfQ91eZlclChAJ9wIg5uxlOk3+03L/40ca0bO+jF23m6MbIXIoJMZAw/7Q5S2j\nk6MQDiTh7uZSM7KuCXY5cWpHaZdg5Zuw9UvjROljc6F6B7OrEgWUhLsby8zKJuQN40LhexpUYlq/\nRiZX5MZiVhrj1pPjofkQ6PAG+BQzuypRgEm4u6nd8Rfo9fEGy/33769vYjVu7EoSLHvVuNK0TC34\nzzKocn13DiEcT8LdDf2+PZ7hs3cB4OWhiB7flUJecpGMTWlt9IJZPMLo5Nh2BLQbKY2+hNOQcHcj\np5NT6fPpBk4mpwLQIaQcMwY0NbkqN3TptNG9cf9CqNgA+v8OFeU/I+FcJNzdROy5y3T88H8nTuc9\n25qGgSVMrMgNaQ07fzQOw2SmQac3oeVQ8JRfI+F85KfSDfy85Riv/L4HgNY1SvPDwOZyxamtnY+D\nBS/A4TVQpZXR6KtMDbOrEuKmJNxd3DuL/2b6WqNHW1hAcX4c1MLkitxMdhZs+RJWvQnKA3p8CE3+\nI42+hNOTcHdhS/eesgT7wufaEBpQ3OSK3My5A0ajr/gtUKMz9JwCJQLzfp4QTkDC3UWdTk5lyA/b\nAZjar5EEuy1lZcD6j2Dt+1CoKNw3Heo/JI2+hEuRcHdBudv1Dm5XjV4yDZ7tnNxh7K2f2Qv1+kC3\n96FYWbOrEuK2Sbi7kKSUdNq9v5rLaZkABJUuwqiuISZX5SYyrsKaifDXNChaDvr+BCE9zK5KiHyT\ncHcRWdn6mlmTfhrUnFY1yphYkRuJ2wCRz0FSLDR+HDpPgMIyjFS4Ngl3F7DmwFkGzPzfdLRx78oe\npU2kXjSmu4v6GkpUhcfnQ7UIk4sSwjYk3J3ct3/FMTZyHwB+Pl7MH9ra5IrcxMHlsHAYXDwJLZ6F\nDq8ZJ0+FcBMS7k5sdtRxS7BP7BNG36aBcnHSnUpJhKWjYc9sKBsCA1dAoLRoEO5Hwt2JvZwzImZq\nv0YyIuZOaQ37fofFL0PqBWg/Ctq+BF4+ZlcmhF1IuDup40lXAPD0UBLsd+riKVg0HA4shkqNoHck\nlK9ndlVC2JWEu5O69xOjF/uv/qrxAAAUlElEQVTHMsFG/mkN27+D5W9AVhrc/RY0f1oafYkCQX7K\nndD3G+NITEkHoEu9CuYW46qSjsCC5+HIWqjaBnpNhdLVza5KCIeRcHdCn6yOBWDB0DZ4eMgJ1NuS\nnQWbP4dVE8DDC3p+BI2fkEZfosCRcHcyV9IzOX3RmGwjrLL0i7ktZ6Ihciic2AY1uxiNvooHmF2V\nEKaQcHcif8Um8MiXmwEY3rmWydW4kMx0WD8Z1k4CX3+4/2sIvV8afYkCTcLdSayMPsOg76Is9x9v\nWdXEalzIiW1Go6+z0RD2IHR9F4pKWwYhJNydwJQVB/nvqkMAPN+hBsPvrm1yRS4g/Qqsfhs2fQrF\nKkC/WVC7m9lVCeE0JNxNNvq33czaehyAZyKqS7Bb48haiHwezh+BJk9C5zfBV85PCJGbhLuJthxJ\nsgT7zAFNuSuknMkVObnUZFgxBrZ9AyWD4YkFENzO7KqEcEpWjQ9TSnVVSh1QSsUopUbfYr37lVJa\nKRVuuxLdU1JKOg99sRGAmU9KsOfpwBL4pLlxUVKr5+DpvyTYhbiFPPfclVKewCdAZyAe2KqUitRa\nR1+3nh/wArDZHoW6kwtX0i292cv5+XBXbQn2m0pJgCWjYO+vUK4e9P0RApqYXZUQTs+aPfdmQIzW\n+rDWOh2YBfS+wXoTgPeAVBvW53a01jQcbwR7mWI+bHmtk8kVOSmtYfcc+LgpRM+HiFdh8BoJdiGs\nZE24BwDHc92Pz1lmoZRqDARqrRfZsDa39OPmY5bbW1/raGIlTiz5BPzcF34fBKWqwZB1EDEKvAqZ\nXZkQLuOOT6gqpTyAycAAK9YdDAwGqFKlyp2+tcvZciSJ1+ftBWDR822kN/v1srNh+zewfAxkZ0KX\nd6D5EPDwNLsyIVyONeF+AgjMdb9yzrJ/+AGhwJqcsKoARCqlemmto3Kth9Z6OjAdIDw8XN9B3S5n\n1pZjjP59DwB9GgVQr5IM3btGYqwxvPHoeuNE6T1ToVSw2VUJ4bKsCfetQE2lVDBGqPcFHvnnQa11\nMmC5JFAptQYYcX2wF2SJl9Mswf5/7arxSvc6JlfkRLIyjQuRVr8Nnj7Qaxo0ekxaBwhxh/IMd611\nplJqKLAM8ARmaK33KaXGA1Fa60h7F+nKsrI1/b/eAsA9DSpJsOd2eq/R6OvkDqjdA3p8CP4Vza5K\nCLdg1TF3rfViYPF1y8bcZN2IOy/LfXT8cA1xicasSm/fF2pyNU4iMw3WfWh8+ZaAB2ZCvftkb10I\nG5IrVO3o5IWrlmBfMyICf19vkytyAse3Gnvr5/ZD/YeNRl9FSpldlRBuR8LdTj5bE8t7S/cD8N79\nYQSVKWpyRSZLT4E/3oJNn4F/JXhkDtS62+yqhHBbEu528k+wD2oTzEPhgXms7eYOrzFGwlw4CuED\nodM4o++6EMJuJNzt4IVZOwAILFWY13vWNbkaE129AMtfhx3fQ6nqMGAxBLU2uyohCgQJdxv7bmMc\n83eeBOCHgc3NLcZM+xfBwuGQcg5aD4OI0eBd2OyqhCgwJNxtKPbcZcbM3wfA3GdaUbV0ATzOfvks\nLHkZ9s2F8mHwyCyo1MjsqoQocCTcbeRU8lU6fvgnAD3qV6RRlZImV+RgWsPuX2DpaOPkaYfXjT12\nTxkhJIQZJNxtICtb03LiH4BxodK0fgVsT/XCcVj4IsSsgMrNoPfHUFZmlBLCTBLuNlB/3DIAPBQF\nK9izsyHqa1g5DnQ2dH0Pmj0ljb6EcAIS7nco+uRFUtKzjNvju5pcjQMlxEDkc3DsL6h2F9zzEZQM\nMrsqIUQOCfc7NOjbrQD8/FQLfL0LwB5rViZsnAarJ4K3L/T+FBo+Iq0DhHAyEu75pLVm+OxdnEw2\nJp5qUa0AXEJ/eg/MfxZO7YKQnkajL78KZlclhLgBCfd8+mHTUebuMNraf96/iXtPvJGRCms/gA0f\nQeFS8NB3UPdGMy0KIZyFhHs+LN17mjdyxrNvfa0TZf18TK7Ijo5tNhp9JRyEBo9Al7el0ZcQLkDC\nPR9GztkFwNMR1d032NMuw6rxsGU6FK8M/X+DGjKZtxCuQsL9Nh1NTOFSWiZVSxdhVNcQs8uxj5hV\nsGAYJB83hjZ2HAM+fmZXJYS4DRLut0FrTfsP1gDQr5kbTvB99Twsew12/gila8KTS6BqS7OrEkLk\ng4T7bXhzQTQAASUKM6R9dZOrsbHoSFg8AlISoM1waD/KGOoohHBJEu5WysrWfPNXHAArh7c3txhb\nunTGCPW/I6FCGDw6Byo2MLsqIcQdknC3Qna2pvqrxhSyoQH+FC7kBhcraQ07f4Jlr0LGVeO4eqvn\npdGXEG5Cwt0KM3P22JWC355uZW4xtnD+KCwcBrF/QGAL6DUNytYyuyohhA1JuFvh4z8OAbD6pQh8\nvFx4rz07G7Z+CSvfNP5SdZ9kTHvn4WF2ZUIIG5NwvwWtNZ2nrOX8lQxKFvF27Umuzx00Gn0d3wTV\nOxqNvkq44YgfIQQg4X5LK6LPEHP2MgAzn2xmcjX5lJUBG/4Lf74H3kXg3s+hQV9p9CWEm5Nwv4Vv\nN8YBxuiYGuWKmVpLvpzcabQOOL3H6AXTfRIUK2d2VUIIB5Bwv4nMrGw2xCQCUL2six2Oybhq7Klv\nmApFy8BD30PdXmZXJYRwIAn3G7iSnkndMcbsSm1rlnGtjo9HNxp764kx0Kg/3P0WFC5g87kKISTc\nb+SfYPfyUHz9RFOTq7FS2iVjFMzWL40TpY/Ng+p3mV2VEMIkEu7XOXnhquX2gbe64enhAnvth1YY\njb4unoDmT0OH18HHBc8RCCFsRsI9l4upGbR69w8AXu9Rx/mD/UoSLH0Fds+CMrVh4HIIdNFRPUII\nm5Jwz3ElPZP645Zb7g9qW83EavKgNUTPg8UjjU6O7UYaX15u2lteCHHbrLo0USnVVSl1QCkVo5Qa\nfYPHhyulopVSu5VSq5RSVW1fqn2NnLMbMIZ/x7zdzeRqbuHSafilP8wZAP4BMHiNcRhGgl0IkUue\ne+5KKU/gE6AzEA9sVUpFaq2jc622AwjXWl9RSj0NvA88bI+C7eF0ciqL9pwCIPbt7ng44+EYrWHH\nD0a/9aw06DweWjwLnvLPlxDi36xJhmZAjNb6MIBSahbQG7CEu9Z6da71NwH9bVmkPU1ecZCpq4ze\nMd1CKzhnsJ+PgwUvwOE1ULU13DMVytQwuyohhBOzJtwDgOO57scDzW+x/kBgyY0eUEoNBgYDVKli\nfl+TQ2cuWYL93oaV+OBBJ+tjnp1lzGG6ajwoT+gxGZo8KY2+hBB5sun/9Eqp/kA4cMPZLLTW04Hp\nAOHh4dqW750fnaesBeDLx8PpXLe8ydVc5+x+42Kk+K1Qo7PR6Kt4ZbOrEkK4CGvC/QQQmOt+5Zxl\n11BKdQJeA9prrdNsU579LN932nLbqYI9Mx02fARrP4BCxaDPlxD2oDT6EkLcFmvCfStQUykVjBHq\nfYFHcq+glGoEfAF01VqftXmVNpaakcXg77cB8N1/nGhc+IntRlveM3sh9H7o+h4UK2t2VUIIF5Rn\nuGutM5VSQ4FlgCcwQ2u9Tyk1HojSWkcCHwDFgDk5fViOaa2dslNVdrYm5I2lALSqXpp2tZwgPDOu\nwup3YOPHUKw89P0ZQrqbXZUQwoVZdcxda70YWHzdsjG5bneycV128+hXmy23v3GGHu1x64299aTD\n0PgJY4hj4RJmVyWEcHEFapB0drZm42Gjje+ecXdTyMvEUSepF2HlWIiaASWD4PFIqHbD89BCCHHb\nClS4/7TlGAA961fEz9fbvEIOLoOFL8KlU9ByKNz1KhRysZ7xQginVmDCXWvN6/P2AvBajzrmFJGS\nCEtHw57ZUDYEHvoOKoebU4sQwq0VmHDfGnfecrti8cKOfXOtYe9vsORl43BM+9HQdrj0gxFC2E2B\nCfdJyw4AsPj5to5944snYdFLcGAxVGoMvT+G8vUcW4MQosBx+3DXWlPjtSVkZRsXxNap6OeoN4bt\n38LyNyArw5jursUz4OHpmPcXQhRobh/u/b7cZAn2VS+1d8x8qEmHIfJ5iFsHQW3hnv9C6er2f18h\nhMjh1uG++sBZNh1OAuDgW93sP/QxOws2fQZ/vAWe3tDzI2PsujT6EkI4mFuH+5MztwLw7X+a2T/Y\nz0Qbjb5ObINaXY0OjsUD7PueQghxE24b7usOnQMgpIIf7e3ZYiAzHdZPhrWTwNcf7v/a6Asjjb6E\nECZyy3A/czGVx77eAsDb94Xa743itxl762ejjc6NXd+DoqXt935CCGEltwz3fybgqF3ejyZVS9n+\nDdKvwOq3YdOnUKwC9PsFane1/fsIIUQ+uV24J6Wk8+Nmo83A3Gdb2f4Njqw1Gn2djzNmRer8JvgW\nt/37CCHEHXC7cP8rNgGALvXKU6SQDTcvNdkYs779WygZDE8shGAHXxAlhBBWcrtwf/nX3QCMuceG\nV4EeWGI0+rp8Blo9BxGvQqEitnt9IYSwMbcK9ykrDnIlPQuAgBI26B+TkmD0g9n7G5SrB31/hIAm\nd/66QghhZ24V7vtOXgRg7ci77uyFtIY9c2DJKEi7BHe9Bq2HgVchG1QphBD251bhvvLvM4QFFKdK\n6Ts4ZJIcDwuHw6FlEBBuNPoqZ1KLYCGEyCe3CfcNMcaJ1LTMrPy9QHY2bJsJK8aCzoIuE6H5/0mj\nLyGES3KbcH/mx+0ATH6o4e0/OTHWaPR1dD0EtzcafZUKtnGFQgjhOG4R7kcTU0i+mkFZPx9CA25j\nzHlWJmz6BFa/A54+0GsaNHpMWgcIIVyeW4T7TzkXLY28u7b1Tzq912gdcHIH1O4BPT4E/4p2qlAI\nIRzLLcL9+PkrANzfpHLeK2emGU2+1k+GwiXhwW+g7r2yty6EcCtuEe6Fvb3w9FB4euQR0Me3wPyh\nkHAA6veFrhOhiB16zwghhMncItxPXLhCYMlbXLSUngKrJsDmz8E/AB79FWp2dlyBQgjhYC4f7mcu\nprLpcBLBZYreeIXY1bDgebhwDJoOgo5jjb7rQgjhxlw+3H/dFg9ARO3rJuS4egGWvwY7foBS1WHA\nYghqbUKFQgjheC4f7ov3nAJgVNeQ/y38eyEseglSzkGbF6H9KPC2Qa8ZIYRwES4d7lprSz8ZX29P\nuHwWFo+E6HlQPgwemQWVGplcpRBCOJ5Lh/uqv88C0K5mGdj5MywdDRlXoMMb0PoF8PQ2uUIhhDCH\nhzUrKaW6KqUOKKVilFKjb/C4j1Lql5zHNyulgmxd6I3M23mCSiTwuZoI84ZAmVowZD20GyHBLoQo\n0PLcc1dKeQKfAJ2BeGCrUipSax2da7WBwHmtdQ2lVF/gPeBhexT8j+V7T1Jy37cs95lFkVOe0O19\nYzSMNPoSQgir9tybATFa68Na63RgFtD7unV6A9/m3P4V6KiUfS75TM/M5pn//kKJ2fcywfsbEks2\ngGc2SgdHIYTIxZpj7gHA8Vz344HmN1tHa52plEoGSgMJtigyt52R05iSNIFU5c2Oxu/Q6J5npHWA\nEEJcx6EnVJVSg4HBAFWqVMnfi5SuznbfZjR7dgaN/CvYsDohhHAf1oT7CSAw1/3KOctutE68UsoL\nKA4kXv9CWuvpwHSA8PBwnZ+Cm7XvCe175uepQghRYFhzzH0rUFMpFayUKgT0BSKvWycSeCLn9gPA\nH1rrfIW3EEKIO5fnnnvOMfShwDLAE5ihtd6nlBoPRGmtI4Gvge+VUjFAEsYfACGEECax6pi71nox\nsPi6ZWNy3U4FHrRtaUIIIfLLqouYhBBCuBYJdyGEcEMS7kII4YYk3IUQwg1JuAshhBtSZg1HV0qd\nA47m8+llsENrAycn21wwyDYXDHeyzVW11mXzWsm0cL8TSqkorXW42XU4kmxzwSDbXDA4YpvlsIwQ\nQrghCXchhHBDrhru080uwASyzQWDbHPBYPdtdslj7kIIIW7NVffchRBC3IJTh7uzTsxtT1Zs83Cl\nVLRSardSapVSqqoZddpSXtuca737lVJaKeXyIyus2Wal1EM5n/U+pdRPjq7R1qz42a6ilFqtlNqR\n8/Pd3Yw6bUUpNUMpdVYptfcmjyul1NSc78dupVRjmxagtXbKL4z2wrFANaAQsAuoe906zwCf59zu\nC/xidt0O2Oa7gCI5t58uCNucs54fsBbYBISbXbcDPueawA6gZM79cmbX7YBtng48nXO7LhBndt13\nuM3tgMbA3ps83h1YAiigBbDZlu/vzHvuTjUxt4Pkuc1a69Va6ys5dzdhzIzlyqz5nAEmAO8BqY4s\nzk6s2eangE+01ucBtNZnHVyjrVmzzRrwz7ldHDjpwPpsTmu9FmN+i5vpDXynDZuAEkqpirZ6f2cO\n9xtNzB1ws3W01pnAPxNzuyprtjm3gRh/+V1Zntuc8+9qoNZ6kSMLsyNrPudaQC2l1Aal1CalVFeH\nVWcf1mzzOKC/UioeY/6I5xxTmmlu9/f9tjh0gmxhO0qp/kA40N7sWuxJKeUBTAYGmFyKo3lhHJqJ\nwPjvbK1SKkxrfcHUquyrH/CN1vpDpVRLjNndQrXW2WYX5oqcec/9dibm5lYTc7sQa7YZpVQn4DWg\nl9Y6zUG12Ute2+wHhAJrlFJxGMcmI138pKo1n3M8EKm1ztBaHwEOYoS9q7JmmwcCswG01hsBX4we\nLO7Kqt/3/HLmcC+IE3Pnuc1KqUbAFxjB7urHYSGPbdZaJ2uty2itg7TWQRjnGXppraPMKdcmrPnZ\nnoex145SqgzGYZrDjizSxqzZ5mNARwClVB2McD/n0CodKxJ4PGfUTAsgWWt9ymavbvYZ5TzONnfH\n2GOJBV7LWTYe45cbjA9/DhADbAGqmV2zA7Z5JXAG2JnzFWl2zfbe5uvWXYOLj5ax8nNWGIejooE9\nQF+za3bANtcFNmCMpNkJ3G12zXe4vT8Dp4AMjP/EBgJDgCG5PuNPcr4fe2z9cy1XqAohhBty5sMy\nQggh8knCXQgh3JCEuxBCuCEJdyGEcEMS7kII4YYk3IUQwg1JuAshhBuScBdCCDf0/0/oXujaMFB8\nAAAAAElFTkSuQmCC\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PIdhwfgzIYII",
        "colab_type": "text"
      },
      "source": [
        " **看看您是否可以调整任务 2 中训练的模型的学习设置，以改善 AUC。**\n",
        "\n",
        "通常情况下，某些指标在提升的同时会损害其他指标，因此您需要找到可以实现理想折中情况的设置。\n",
        "\n",
        "**验证所有指标是否同时有所提升。**"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XKIqjsqcCaxO",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "# TUNE THE SETTINGS BELOW TO IMPROVE AUC\n",
        "linear_classifier = train_linear_classifier_model(\n",
        "    learning_rate=0.000005,\n",
        "    steps=500,\n",
        "    batch_size=20,\n",
        "    training_examples=training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=validation_examples,\n",
        "    validation_targets=validation_targets)\n",
        "\n",
        "evaluation_metrics = linear_classifier.evaluate(input_fn=predict_validation_input_fn)\n",
        "\n",
        "print(\"AUC on the validation set: %0.2f\" % evaluation_metrics['auc'])\n",
        "print(\"Accuracy on the validation set: %0.2f\" % evaluation_metrics['accuracy'])"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wCugvl0JdWYL",
        "colab_type": "text"
      },
      "source": [
        " ### 解决方案\n",
        "\n",
        "点击下方即可查看可能的解决方案。"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VHosS1g2aetf",
        "colab_type": "text"
      },
      "source": [
        " 一个可能有用的解决方案是，只要不过拟合，就训练更长时间。\n",
        "\n",
        "要做到这一点，我们可以增加步数和/或批量大小。\n",
        "\n",
        "所有指标同时提升，这样，我们的损失指标就可以很好地代理 AUC 和准确率了。\n",
        "\n",
        "注意它是如何进行很多很多次迭代，只是为了再尽量增加一点 AUC。这种情况很常见，但通常情况下，即使只有一点小小的收获，投入的成本也是值得的。"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "dWgTEYMddaA-",
        "colab_type": "code",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 567
        },
        "outputId": "b29f9455-0dca-405c-ba0c-58b4351a4196"
      },
      "source": [
        "linear_classifier = train_linear_classifier_model(\n",
        "    learning_rate=0.000003,\n",
        "    steps=20000,\n",
        "    batch_size=500,\n",
        "    training_examples=training_examples,\n",
        "    training_targets=training_targets,\n",
        "    validation_examples=validation_examples,\n",
        "    validation_targets=validation_targets)\n",
        "\n",
        "evaluation_metrics = linear_classifier.evaluate(input_fn=predict_validation_input_fn)\n",
        "\n",
        "print(\"AUC on the validation set: %0.2f\" % evaluation_metrics['auc'])\n",
        "print(\"Accuracy on the validation set: %0.2f\" % evaluation_metrics['accuracy'])"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "stream",
          "text": [
            "Training model...\n",
            "LogLoss (on training data):\n",
            "  period 00 : 0.49\n",
            "  period 01 : 0.48\n",
            "  period 02 : 0.47\n",
            "  period 03 : 0.47\n",
            "  period 04 : 0.47\n",
            "  period 05 : 0.47\n",
            "  period 06 : 0.47\n",
            "  period 07 : 0.47\n",
            "  period 08 : 0.47\n",
            "  period 09 : 0.47\n",
            "Model training finished.\n",
            "AUC on the validation set: 0.81\n",
            "Accuracy on the validation set: 0.79\n"
          ],
          "name": "stdout"
        },
        {
          "output_type": "display_data",
          "data": {
            "image/png": "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\nrkJggg==\n",
            "text/plain": [
              "<Figure size 432x288 with 1 Axes>"
            ]
          },
          "metadata": {
            "tags": []
          }
        }
      ]
    }
  ]
}